﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Sidvall.Net.Mail
{
    public class SendGridSmtpClient : ISmtpClient
    {
        #region Public Members

        #region SendAsync

        public async Task SendAsync(MailMessage message)
        {
            string apiKey;

            if (message == null)
                throw new System.ArgumentNullException(nameof(message));

            var recipientAddresses = GetMailAddresses(message.GetRecipientAddressArray());
            var replyToAddresses = GetMailAddresses(message.GetReplyToAddressArray());
            var ccRecipientAddresses = GetMailAddresses(message.GetCCRecipientAddressArray());
            var bccRecipientAddresses = GetMailAddresses(message.GetBccRecipientAddressArray());

            var mail = new SendGrid.Helpers.Mail.Mail()
            {
                Personalization = new List<SendGrid.Helpers.Mail.Personalization>(),
            };
            var personalization = new SendGrid.Helpers.Mail.Personalization();
            mail.Personalization.Add(personalization);
            personalization.Subject = message.Subject;
            if (message.IsBodyHtml)
            {
                var content = new SendGrid.Helpers.Mail.Content("text/html", message.Body);
                mail.AddContent(content);
            }
            else
            {
                var content = new SendGrid.Helpers.Mail.Content("text/plain", message.Body);
                mail.AddContent(content);
            }
            if (!string.IsNullOrWhiteSpace(message.FromAddress))
                mail.From = new SendGrid.Helpers.Mail.Email(message.FromAddress);
            else
                mail.From = new SendGrid.Helpers.Mail.Email(SendGridSystemContext.Current.FromAddress);
            foreach (var recipientAddress in recipientAddresses)
                personalization.AddTo(recipientAddress);
            mail.ReplyTo = replyToAddresses.FirstOrDefault();
            foreach (var ccRecipientAddress in ccRecipientAddresses)
                personalization.AddCc(ccRecipientAddress);
            foreach (var bccRecipientAddress in bccRecipientAddresses)
                personalization.AddBcc(bccRecipientAddress);
            if (message.Attachments != null)
            {
                foreach (var attachment in message.Attachments)
                {
                    var name = message.Attachments.GetNameResolved(attachment);
                    var attachmentContent = await attachment.GetBase64ContentAsync().ConfigureAwait(false);
                    if (attachmentContent != null)
                    {
                        var extension = System.IO.Path.GetExtension(name);
                        var attachmentType = Sidvall.Net.Mime.MediaTypeManager.GetMediaTypeNameFromFileExtension(extension);
                        var att = new SendGrid.Helpers.Mail.Attachment()
                        {
                            ContentId = name,
                            Content = attachmentContent,
                            Disposition = "attachment",
                            Filename = name,
                            Type = attachmentType,
                        };
                        mail.AddAttachment(att);
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(message.ConnectionString))
                apiKey = message.ConnectionString;
            else
                apiKey = SendGridSystemContext.Current.ApiKey;
            string requestBody = mail.Get();
            dynamic sg = new SendGrid.SendGridAPIClient(apiKey);
            dynamic response = sg.client.mail.send.post(requestBody: requestBody);
        }

        #endregion
        #region ToString

        public override string ToString()
        {
            return "SmtpClient - SendGrid";
        }

        #endregion

        #endregion
        #region Private Members

        #region GetMailAddresses

        private SendGrid.Helpers.Mail.Email[] GetMailAddresses(IEnumerable<string> addresses)
        {
            var items = new List<SendGrid.Helpers.Mail.Email>();
            if (addresses != null)
            {
                foreach (var address in addresses)
                {
                    var item = new SendGrid.Helpers.Mail.Email(address);
                    items.Add(item);
                }
            }
            return items.ToArray();
        }

        #endregion

        #endregion
    }
}
